package pub.gll.plugin.asm.annotation;


import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;

import pub.gll.plugin.util.CheckClass;
import pub.gll.plugin.util.ClassUtil;
import pub.gll.plugin.util.CloseUtil;

public class ArchInterfaceCheckVisitor extends ClassVisitor {

    public ArchInterfaceCheckVisitor(int api, ClassVisitor classVisitor) {
        super(api, classVisitor);
    }

    @Override
    public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) {
        return new InterfaceCheckFileAnnotationVisitor(Opcodes.ASM7, super.visitField(access, name, descriptor, signature, value), descriptor);
    }

    private class InterfaceCheckFileAnnotationVisitor extends FieldVisitor {

        private String desc;

        public InterfaceCheckFileAnnotationVisitor(int api) {
            super(api);
        }

        public InterfaceCheckFileAnnotationVisitor(int api, FieldVisitor fieldVisitor, String descriptor) {
            super(api, fieldVisitor);
            this.desc = descriptor;
        }

        @Override
        public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
            if (CheckClass.isNeedInterfaceTypeAnnotation(descriptor)) {
                String resultClassPath = desc.replace("Lcom",  "com");
                resultClassPath = resultClassPath.replace(";",  "");
               boolean isInterface = ClassUtil.isInterface(resultClassPath);
               if (!isInterface) {
                   CloseUtil.exit("arch field "+ resultClassPath +" type need to be interface!");
               }
            }

            return super.visitAnnotation(descriptor, visible);
        }
    }
}
